package com.hyacinth.cloudnote.common.dto.result;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 抽象返回结果对象
 */
@NoArgsConstructor
@Getter
@Setter
//为了使用Getter，去掉了abstract修饰符，不过构造函数是protected的，不影响设计
public class AbstractResultDTO implements Serializable {
    private static final long serialVersionUID = -6039287130311081003L;

    /**
     * HTTP结果状态
     */
    @ApiModelProperty(value = "HTTP结果状态")
    @JsonProperty(index = 0)
    private int status;

    /**
     * 错误
     */
    @ApiModelProperty(value = "错误", position = 1)
    @JsonProperty(index = 1)
    private String error;

    /**
     * 关联信息
     */
    @ApiModelProperty(value = "关联信息", position = 2)
    @JsonProperty(index = 2)
    private String message;

    /**
     * 请求URI
     */
    @ApiModelProperty(value = "请求URI", position = 3)
    @JsonProperty(index = 3)
    private String path;

    /**
     * 时间戳
     */
    @ApiModelProperty(value = "时间戳", position = 4)
    @JsonProperty(index = 4)
    private LocalDateTime timestamp;

    /**
     * 错误详细
     */
    @ApiModelProperty(value = "错误详细", position = 5)
    @JsonProperty(index = 5)
    private ErrorDetailDTO[] errorDetails;

    protected AbstractResultDTO(final HttpStatus status) {
        this(status.value(), null, status.getReasonPhrase(), null, null);

        if (!status.equals(HttpStatus.OK)) {
            this.error = status.getReasonPhrase();
            this.message = "请求处理失败。";
        }
    }

    protected AbstractResultDTO(final int status, final String error, final String message, final String path, final ErrorDetailDTO[] errorDetails) {
        this.status = status;
        this.error = error;
        this.message = message;
        this.path = path;
        this.timestamp = LocalDateTime.now();
        this.errorDetails = errorDetails;

    }

    @JsonIgnore
    public boolean isFailure() {
        return this.error != null;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.error == null;
    }

    @JsonIgnore
    public String errorDetails1() {
        if ((this.errorDetails != null) && (this.errorDetails.length > 0)) {
            final StringBuilder builder = new StringBuilder();
            builder.append("Errors : [");
            for (final ErrorDetailDTO error : this.errorDetails) {
                builder.append(error.toString());
            }
            builder.append("]");
            return builder.toString();
        } else {
            return "errors : []";
        }
    }
}
